package com.example.mybatisplusproject.plugins;

import com.example.mybatisplusproject.annotation.EncryptDecryptClass;
import com.example.mybatisplusproject.endecrypt.IEncryptDecrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author zls
 * @date 2021/8/1 9:36 下午
 */
@Intercepts(
        @Signature(
                type = ResultSetHandler.class,
                method = "handleResultSets",
                args = Statement.class
        )
)
@Component
@Slf4j
public class DecryptInteceptor implements Interceptor {

    @Autowired
    private IEncryptDecrypt encryptDecrypt;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取执行结果
        Object result = invocation.proceed();
        if (result == null) {
            return null;
        }
        if (result instanceof List) {
            ArrayList list = (ArrayList) result;
            if (CollectionUtils.isNotEmpty(list) && needDecrypt(list.get(0))) {
                for (Object o : list) {
                    encryptDecrypt.decrypt(o);
                }
            }
            return list;
        }
        if (needDecrypt(result)) {
            encryptDecrypt.decrypt(result);
        }
        return result;
    }

    private boolean needDecrypt(Object result) {
        EncryptDecryptClass annotation = AnnotationUtils.findAnnotation(result.getClass(), EncryptDecryptClass.class);
        return Objects.nonNull(annotation);
    }
}
